﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using RuoVea.ExConfig;
using RuoVea.ExSugar;
using RuoVea.OmiApi.Dict.Entitys;
using RuoVea.OmiApi.Dict.SeedData;
using RuoVea.OmiApi.Dict.Service;
using SqlSugar;

namespace RuoVea.OmiApi.Dict;

/// <summary>
/// 注入扩展
/// </summary>
public static class ServiceCollectionExtensions
{
    /// <summary>
    /// 字典管理
    /// </summary>
    /// <param name="services"></param>
    /// <param name="serviceLifetime">Scoped</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiDictSetup(this IServiceCollection services, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        services.Configure<DbInitConfig>(AppSettings.Configuration.GetSection("DbInitConfig"));
        return DI(services, null, serviceLifetime);
    }

    /// <summary>
    /// 字典管理
    /// </summary>
    /// <param name="services"></param>
    /// <param name="config"></param>
    /// <param name="serviceLifetime">Scoped</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiDictSetup(this IServiceCollection services, IConfiguration config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (config == null) throw new ArgumentNullException(nameof(config));
        services.Configure<DbInitConfig>(config);
        DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
        return DI(services, dbInitConfig, serviceLifetime);
    }

    /// <summary>
    /// 字典管理
    /// </summary>
    /// <param name="services"></param>
    /// <param name="config"></param>
    /// <param name="serviceLifetime">Scoped</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddOmiDictSetup(this IServiceCollection services, Action<DbInitConfig> config, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (config == null) throw new ArgumentNullException(nameof(config));
        services.Configure(config);
        DbInitConfig dbInitConfig = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
        return DI(services, dbInitConfig, serviceLifetime);
    }

    #region DI
    private static IServiceCollection DI(IServiceCollection services, DbInitConfig dbInitConfig, ServiceLifetime serviceLifetime)
    {
        switch (serviceLifetime)
        {
            case ServiceLifetime.Scoped:
                services.AddScoped<SysDictTypeService>();
                services.AddScoped<SysDictValueService>();
                services.AddScoped<SysDictValueValidator>();
                
                break;
            case ServiceLifetime.Singleton:
                services.AddSingleton<SysDictTypeService>();
                services.AddSingleton<SysDictValueService>();
                services.AddSingleton<SysDictValueValidator>();
                break;
            case ServiceLifetime.Transient:
                services.AddTransient<SysDictTypeService>();
                services.AddTransient<SysDictValueService>();
                services.AddTransient<SysDictValueValidator>();
                break;
        }
        return services;
    }
    #endregion

    /// <summary>
    /// 字典管理 - 初始化数据库/初始化种子数据
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public static IServiceCollection AddDictInitSetup(this IServiceCollection services)
    {
        Task.Run(() =>
        {
            DbInitConfig config = services.BuildServiceProvider().GetRequiredService<IOptions<DbInitConfig>>()?.Value;
            var _thisRepository = services.BuildServiceProvider().GetRequiredService<ISqlSugarClient>();
            if (config.InitTable && _thisRepository != null)
            {
                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(SysDictType), false) || _thisRepository.DbMaintenance.IsAnyTable("sys_dict_type", false)) { }
                else
                {
                    _thisRepository.CodeFirst.InitTables<SysDictType>();
                    if (config.InitSeedData)
                        _thisRepository.Storageable(new SysDictTypeSeedData().HasData().ToList()).ToStorage().AsInsertable.ExecuteCommand();
                }
                if (_thisRepository.DbMaintenance.IsAnyTable(nameof(SysDictValue), false) || _thisRepository.DbMaintenance.IsAnyTable("sys_dict_value", false)) { }
                else
                {
                    _thisRepository.CodeFirst.InitTables<SysDictValue>();
                    if (config.InitSeedData)
                        _thisRepository.Storageable(new SysDictValueSeedData().HasData().ToList()).ToStorage().AsInsertable.ExecuteCommand();
                }
            }
        });
        return services;
    }
}
